package com.kim.common.utilcom.redis;

import com.kim.common.utilcom.redis.serializer.RedisObjectSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis 配置
 */
@Slf4j
@Configuration
public class RedisConfig {

    /**
     * 生菜链接工厂
     */
    private final LettuceConnectionFactory lettuceConnectionFactory;

    public RedisConfig(LettuceConnectionFactory lettuceConnectionFactory) {
        this.lettuceConnectionFactory = lettuceConnectionFactory;
    }

    /**
     * redis集群配置
     */
    @Primary
    @Bean("redisTemplate")
    @ConditionalOnProperty(name = "spring.redis.cluster.nodes")
    public RedisTemplate<String, Object> getRedisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        RedisSerializer<Object> redisObjectSerializer = new RedisObjectSerializer();
        // key的序列化类型
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        // value的序列化类型
        redisTemplate.setValueSerializer(redisObjectSerializer);
        redisTemplate.setHashValueSerializer(redisObjectSerializer);
        redisTemplate.afterPropertiesSet();
        redisTemplate.opsForValue().set("test", "qipp");
        log.info("Create redisTemplate ---> spring.redis.cluster.nodes ");
        return redisTemplate;
    }

    /**
     * redis 单击配置类
     * <p>
     * FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
     * ObjectMapper mapper = new ObjectMapper();
     * mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
     * mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
     * serializer.setObjectMapper(mapper);
     */
    @Primary
    @Bean("redisTemplate")
    @ConditionalOnProperty(name = "spring.redis.host", matchIfMissing = true)
    public RedisTemplate<String, Object> getSingleRedisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        RedisSerializer<Object> redisObjectSerializer = new RedisObjectSerializer();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        // key的序列化类型
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(redisObjectSerializer);
        redisTemplate.setHashValueSerializer(redisObjectSerializer);
        redisTemplate.afterPropertiesSet();
        log.info("Create redisTemplate ---> spring.redis.host ");
        return redisTemplate;
    }

    /*
     * @ConditionalOnProperty
     *
     * value
     * String数组  该属性与下面的 name 属性不可同时使用，
     * 当value所对应配置文件中的值为false时，注入不生效，不为fasle注入生效
     * value有多个值时，只要有一个值对应为false,则注入不成功
     *
     * prefix
     * 配置文件中key的前缀，可与value 或 name 组合使用
     *
     * havingValue
     * 与value 或 name 组合使用，只有当value 或 name 对应的值与havingValue的值相同时，注入生效
     *
     * matchIfMissing
     * 配置中缺少对应的属性时，是否可以被注入；为true时缺少对应配置可注入
     */
}
